/*
 *  Copyright (C) 2003,14 R. De Graeve & B. Parisse,
 *  Institut Fourier, 38402 St Martin d'Heres
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef CASPP_MODELS_BASICS_H
#define CASPP_MODELS_BASICS_H

#include <caspp/config.h>

#include <string>
#include <iostream>
#include <complex>
#include <vector>

#include <boost/thread.hpp>
#include <boost/thread/lockable_adapter.hpp>

CASPP_NS_BEGIN

typedef boost::shared_mutex SharedMutex;
typedef boost::upgrade_lockable_adapter<SharedMutex> UpgradeLockable;

typedef int int_t;

#ifndef CASPP_FLT_EVAL_METHOD
#   define CASPP_FLT_EVAL_METHOD 0
#endif

#if CASPP_FLT_EVAL_METHOD == 0
    typedef float float_t;
    typedef double double_t;
#elif CASPP_FLT_EVAL_METHOD == 1
    typedef double float_t;
    typedef double double_t;
#elif CASPP_FLT_EVAL_METHOD == 2
    typedef double float_t;
    typedef long double double_t;
#elif CASPP_FLT_EVAL_METHOD == 3
    typedef long double float_t;
    typedef long double double_t;
#else /* __FLT_EVAL_METHOD__ */
#   error "Unsupported value of CASPP_FLT_EVAL_METHOD."
#endif /* __FLT_EVAL_METHOD__ */

class int_v: public std::vector<int_t> {
public:
    typedef int_v __self;
    typedef std::vector<int_t> __super;
    // inherited constructors
    int_v()
        : __super() {}
    int_v(size_type i)
        : __super(i) {}
    int_v(size_type i,
          const_reference v)
        : __super(i,v) {}
    int_v(const __self & v)
        : __super(v) {}
    int_v(const __super & v)
        : __super(v) {}
    const std::string description() const;
};

class int_m: public std::vector<int_v> {
public:
    typedef int_m __self;
    typedef std::vector<int_v> __super;
    // inherited constructors
    int_m()
        : __super() {}
    int_m(size_type i)
        : __super(i) {}
    int_m(size_type i,
             const_reference v)
        : __super(i,v) {}
    int_m(const __self & v)
        : __super(v) {}
    int_m(const __super & v)
        : __super(v) {}
    const std::string description() const;
};

class double_v: public std::vector<double_t> {
public:
    typedef double_v __self;
    typedef std::vector<double_t> __super;
    // inherited constructors
    double_v():
        __super() {}
    double_v(size_type i):
        __super(i) {}
    double_v(size_type i,
             const_reference v):
        __super(i,v) {}
    double_v(const __self & v):
        __super(v) {}
    double_v(const __super & v):
        __super(v) {}
    std::string description() const;
};

class double_m: public std::vector<double_v> {
public:
    typedef double_m __self;
    typedef std::vector<double_v> __super;
    // inherited constructors
    double_m():
        __super() {}
    double_m(size_type i):
        __super(i) {}
    double_m(size_type i,
             const_reference v):
        __super(i,v) {}
    std::string description() const;
};

class complex_t: public std::complex<double_t> {
public:
    typedef complex_t __self;
    typedef std::complex<double_t> __super;
    complex_t(const value_type & re = value_type(),
              const value_type & im = value_type())
        : __super(re,im) {}
    complex_t(const __self & v)
        : __super(v) {}
    complex_t(const __super & v)
        : __super(v) {}
    const std::string description() const;
};

class complex_v: public std::vector<complex_t> {
public:
    typedef complex_v __self;
    typedef std::vector<complex_t> __super;
    // inherited constructors
    complex_v():
        __super() {}
    complex_v(size_type i):
        __super(i) {}
    complex_v(size_type i,
             const_reference v):
        __super(i,v) {}
    complex_v(const __self & v):
        __super(v) {}
    complex_v(const __super & v):
        __super(v) {}
    const std::string description() const;
};

class complex_m: public std::vector<complex_v> {
public:
    typedef std::vector<complex_v> __super;
    // inherited constructors
    complex_m():
        __super() {}
    complex_m(size_type i):
        __super(i) {}
    complex_m(size_type i,
              const complex_v v):
        __super(i,v) {}
    const std::string description() const;
};

CASPP_NS_END

#endif // CASPP_MODELS_BASICS_H
